﻿/********
* Copyright © 深圳市新元素医疗技术开发有限公司 . All rights reserved.
* 
*  Description:
*  Create By Kain at 5/21/2011 10:59:45 AM
*  
*
*  Revision History:
*  Date                  Who                 What
*  
* 
********/

#region namespace

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Cherry.Agile.Core;
using Microsoft.Practices.Unity;
using Cherry.Agile.Core.Instrumentation;
using Cherry.Agile.Logging;
using System.ServiceModel;
#endregion

namespace Cherry.Agile.ServiceModel.Runtime.Instrumentation
{
    static class Instrumentation
    {

        static Lazy<IServiceInstrumentationProvider> _serviceInstrumentationProvider =
            new Lazy<IServiceInstrumentationProvider>(LoadServiceInstrumentation);

        static IServiceInstrumentationProvider LoadServiceInstrumentation()
        {
            try
            {
                Math.Max(10, Cherry.Agile.Configuration.AgileConfiguration.Current.ApplicationSection.MinDuration);
            }
            catch
            {

            }

            var instance = Assembly.GetEntryAssembly().FullName.Split(',')[0];
            if (Container.Current.IsRegistered<IServiceInstrumentationProvider>())
                return Container.Current.Resolve<IServiceInstrumentationProvider>(
                    new ParameterOverride("instanceName", instance));
            return null;
        }

        static Lazy<ILogger> _lazyLogger = new Lazy<ILogger>(GetLogger);


        static ILogger GetLogger()
        {
            const string loggerName = "performance";
            return LoggingManager.GetLogger(loggerName);
        }

        private static void WriteLog(int time)
        {
            if (_lazyLogger.Value == null || minValue == 0 || time < minValue)
                return;
            var name = (OperationContext.Current.IncomingMessageHeaders).Action;

            if (time > minValue * 5)
                _lazyLogger.Value.Error(string.Format("Performance\t{0} duration:{1}ms", name, time));
            else
                _lazyLogger.Value.Warn(string.Format("Performance\t{0} duration:{1}ms", name, time));
        }

        static readonly int minValue = 10;

        private static IServiceInstrumentationProvider ServiceInstrumentation
        {
            get
            {
                return _serviceInstrumentationProvider.Value;
            }
        }

        public static void InvokeDuration(int time)
        {
            WriteLog(time);

            if (ServiceInstrumentation != null)
                ServiceInstrumentation.InvokeDuration(time);
        }

        public static void Error()
        {
            if (ServiceInstrumentation != null)
                ServiceInstrumentation.Error();
        }

        public static void InvokeMessageSize(int length)
        {
            if (ServiceInstrumentation != null)
                ServiceInstrumentation.InvokeMessageSize(length);
        }

    }
}
